package com.kx.kxblog.aop;


import com.kx.kxblog.annotation.PermissionLimit;
import com.kx.kxblog.dao.UserDao;
import com.kx.kxblog.entity.User;
import com.kx.kxblog.enums.Permission;
import com.kx.kxblog.enums.ResultCode;
import com.kx.kxblog.enums.SystemContextKey;
import com.kx.kxblog.exception.ResultException;
import com.kx.kxblog.util.SystemContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 权限控制切面
 * 目前主要负责登录和权限校验
 * @author KX
 **/
@Aspect
@Component
public class ControllerAspect {

    @Autowired
    private UserDao userDao;

    /**
     * 定义切入点，切入点为controller中的所有函数
     *通过@Pointcut注解声明频繁使用的切点表达式
     */
     @Pointcut("execution(public * com.kx.kxblog.controller.*.*(..)))")
     public void controllerPointCut(){
     }

    /**
     * 在连接点执行之前执行的通知
     */
    @Before("controllerPointCut()")
    public void beforeController(JoinPoint joinPoint) throws NoSuchMethodException {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        HttpServletResponse response = servletRequestAttributes.getResponse();
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(SystemContextKey.USER.name());
        if(user!=null){
            user = userDao.findById(user.getId()).orElse(null);
            session.setAttribute(SystemContextKey.USER.name(), user);
        }
        SystemContext.put(SystemContextKey.REQUEST, request);
        SystemContext.put(SystemContextKey.RESPONSE, response);
        SystemContext.put(SystemContextKey.SESSION, session);

        Class<?> clazz = joinPoint.getTarget().getClass();
        String methodName = joinPoint.getSignature().getName();
        Class[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
        Method method = clazz.getMethod(methodName, parameterTypes);//获取所访问的方法
        PermissionLimit permissionLimit = method.getAnnotation(PermissionLimit.class);
        if (permissionLimit!=null) {
            if(user==null) {
                throw new ResultException(ResultCode.UNLOGIN);
            } else {
                if(permissionLimit.value()== Permission.ONLY_CREATOR){
                    Object[] args = joinPoint.getArgs();

                }
            }
        }
    }

//    /**
//     * 在连接点执行之后执行的通知（返回通知和异常通知的异常）
//     */
//    @After("controllerPointCut()")
//    public void doAfter(){
//
//    }
//
//    /**
//     * 在连接点执行之后执行的通知（返回通知）
//     */
//    @AfterReturning("controllerPointCut()")
//    public void doAfterReturning(JoinPoint joinPoint){
//
//    }
//
//    /**
//     * 在连接点执行之后执行的通知（异常通知）
//     */
//    @AfterThrowing("controllerPointCut()")
//    public void doAfterThrowing(JoinPoint joinPoint){
//
//    }
}
